/*
 * monster_list.c
 *
 *  Created on: 2013
 *      Author: Eddy Zogbo and Moncef Sbay
 */

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stddef.h>
#include <SDL.h>
#include <SDL_image.h>

#include "../include/game.h"
#include "../include/misc.h"
#include "../include/bomb.h"
#include "../include/monster.h"
#include "../include/bomb_list.h"
#include "../include/monster_list.h"

struct cell_M {
	t_monster monster;
	t_cell_M next;
	t_cell_M previous;
};

struct monster_list {
	t_cell_M first;
};

t_monster_list monster_list_init(t_monster monster) {
	assert(monster);
	t_monster_list monster_list = malloc(sizeof(*monster_list));
	t_cell_M cell_M = malloc(sizeof(*cell_M));
	if (!monster_list || !cell_M)
		error("Memory error");
	cell_M->monster = monster;
	cell_M->next = NULL;
	cell_M->previous = NULL;

	monster_list->first = cell_M;
	return monster_list;
}

t_monster_list create_monster_list(t_monster monster, int nb_monster) {
	t_monster_list monster_list = malloc(sizeof(*monster_list));
	assert(monster);
	monster_list = monster_list_init(monster);
	int i;
	for (i = 1; i < nb_monster; i++) {
		list_add_M(monster_list, monster);
	}
	return monster_list;
}

void list_add_M(t_monster_list monster_list, t_monster monster) {
	assert(monster_list);
	assert(monster);
	t_cell_M cell_M = malloc(sizeof(*cell_M));
	if (!cell_M)
		error("Memory error");

	cell_M->monster = monster;
	cell_M->previous = NULL;
	cell_M->next = monster_list->first;

	monster_list->first->previous = cell_M;
	monster_list->first = cell_M;
}

void monster_list_from_map(t_monster_list monster_list, t_map map) {
	int i, j;
	for (i = 0; i < map_get_width(map); i++) {
		for (j = 0; j < map_get_height(map); j++) {
			if (map_get_cell_type(map, i, j) == CELL_MONSTER) {
				list_add_M(monster_list, monster_place(i, j));
			}
		}
	}
}

t_cell_M get_first_M(t_monster_list monster_list) {
	assert(monster_list);

	return monster_list->first;
}

t_cell_M get_end_M(t_monster_list monster_list) {
	assert(monster_list);
	t_cell_M key = get_first_M(monster_list);
	t_cell_M key1 = key;
	while (get_next_cell_M(key) != NULL) {
		key1 = key;
		key = get_next_cell_M(key);
	}
	return key1;
}

t_monster get_monster(t_cell_M cell_M) {
	assert(cell_M);

	return cell_M->monster;
}

t_cell_M get_next_cell_M(t_cell_M cell_M) {
	assert(cell_M);

	return cell_M->next;
}

t_cell_M get_previous_cell_M(t_cell_M cell_M) {
	assert(cell_M);

	return cell_M->previous;
}

void monster_list_delete(t_monster_list monster_list, t_monster monster) {

	assert(monster_list);

	if (monster_list) {
		t_cell_M key = monster_list->first;

		while (get_next_cell_M(key) != NULL) {
			if (key->monster == monster) {

				if (key->previous == NULL) {
					monster_list->first = get_next_cell_M(key);
					monster_list->first->previous = NULL;
				}

				else if (key->next == NULL) {
					key->previous->next = NULL;
					if (key->previous == NULL) {
						monster_list->first = NULL;
						break;
					}
				}

				else {
					key->previous->next = key->next;
					key->next->previous = key->previous;
				}
				free(key);
			} else
				key = get_next_cell_M(key);
		}
	}
}

void monster_list_update(t_monster_list monster_list) {
	assert(monster_list);
	t_cell_M key = get_end_M(monster_list);
	while (key != NULL) {
		if (has_exploded_M(get_monster(key)) == 1) {
			monster_list_delete(monster_list, get_monster(key));
		}
		key = get_previous_cell_M(key);
	}
}

void monster_list_display(t_monster_list monster_list, t_map map,
		t_player player, SDL_Surface *screen) {
	assert(monster_list);
	assert(screen);
	assert(map);
	assert(player);
	t_cell_M key = get_first_M(monster_list);
	while (key != NULL) {
		monster_display(get_monster(key), map, player, screen);
		key = get_next_cell_M(key);
	}
}

void monster_list_kill(int x, int y, t_monster_list monster_list) {
	assert(monster_list);
	t_cell_M key = get_first_M(monster_list);
	while (key != NULL) {
		monster_kill(x, y, key->monster);
		key = get_next_cell_M(key);
	}
}
